package com.niiwoo.civet.trade.service.dubbo.loan.antifraud;

import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.niiwoo.civet.trade.constant.LoanFlowMqConstant;
import com.niiwoo.civet.trade.constant.MqConstant;
import com.niiwoo.civet.trade.dao.entity.Project;
import com.niiwoo.civet.trade.dao.entity.SystemAuditDecision;
import com.niiwoo.civet.trade.dao.entity.TianChengRequestRecord;
import com.niiwoo.civet.trade.dao.mapper.ProjectMapperExt;
import com.niiwoo.civet.trade.dto.request.ProjectFlowRequestDTO;
import com.niiwoo.civet.trade.dto.request.loan.ProjectFlowExecuteRuntimeDTO;
import com.niiwoo.civet.trade.dto.request.loan.TianChengRequestRecordDTO;
import com.niiwoo.civet.trade.dto.response.loan.AgainstFakeModelV2CallbackRequestDTO;
import com.niiwoo.civet.trade.enums.LoanNodeTypeEnum;
import com.niiwoo.civet.trade.enums.ProjectFlowExecuteRuntimeNodeStatusEnum;
import com.niiwoo.civet.trade.enums.ProjectStatusEnum;
import com.niiwoo.civet.trade.enums.ProjectSubStatusEnum;
import com.niiwoo.civet.trade.enums.ProjectTypeEnum;
import com.niiwoo.civet.trade.enums.TradeConfigEnum;
import com.niiwoo.civet.trade.service.configure.TradeConfigDubboService;
import com.niiwoo.civet.trade.service.loan.antifraud.LoanAntiFraudDubboService;
import com.niiwoo.civet.trade.service.local.flowexecute.ProjectFlowExecuteService;
import com.niiwoo.civet.trade.service.local.loan.TianchengModelParseService;
import com.niiwoo.civet.trade.service.local.loan.antifraud.LoanAntiFraudLocalService;
import com.niiwoo.civet.trade.service.local.loan.antifraud.SystemAuditDecisionLocalService;
import com.niiwoo.civet.trade.service.local.loan.credit.CreditAmountLocalService;
import com.niiwoo.civet.trade.service.project.ProjectDubboService;
import com.niiwoo.civet.user.dto.request.AddUserLoanLimitRequestDTO;
import com.niiwoo.civet.user.dto.request.UserCreditCardAuthInfoDTO;
import com.niiwoo.civet.user.dto.response.credit.BasicInfoDTO;
import com.niiwoo.civet.user.dto.response.credit.ContactPersonInfoDTO;
import com.niiwoo.civet.user.dto.response.credit.CreditScoreCardDTO;
import com.niiwoo.civet.user.dto.response.credit.TianchengCreditBaseInfoResponseDTO;
import com.niiwoo.civet.user.dto.response.credit.WorkInfoDTO;
import com.niiwoo.civet.user.enums.LibraLoanLimitEnum;
import com.niiwoo.civet.user.service.TianchengDataDubboService;
import com.niiwoo.civet.user.service.UserForbidDubboService;
import com.niiwoo.civet.user.service.UserYXCreditCardDubboService;
import com.niiwoo.tripod.provider.exception.BizException;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;
import com.niiwoo.tripod.tiancheng.component.TianchengAgainstFakeV2Service;
import com.niiwoo.tripod.tiancheng.enums.AgainstFakeErrorCodeEnum;
import com.niiwoo.tripod.tiancheng.enums.AntifraudFromSourceEnum;
import com.niiwoo.tripod.tiancheng.enums.FunctionCodeEnum;
import com.niiwoo.tripod.tiancheng.request.afp.KaDaiRepairServiceRequest;
import com.niiwoo.tripod.tiancheng.request.afp.LibraFraudConsumeLoanAgainRequest;
import com.niiwoo.tripod.tiancheng.request.afp.LibraFraudConsumeLoanRequest;
import com.niiwoo.tripod.tiancheng.request.afp.LibraFraudCreditCardFirst;
import com.niiwoo.tripod.tiancheng.request.afp.LibraFraudSocialSecurityNotFirst;
import com.niiwoo.tripod.tiancheng.response.common.AgainstFakeV2Response;

import lombok.extern.slf4j.Slf4j;

/**
 * Created by lujing on 2018/4/19.
 */
@Slf4j
@Service(version = "1.0.0")
public class LoanAntiFraudDubboServiceImpl implements LoanAntiFraudDubboService {

    // 天秤卡贷模型回调地址
    public static final String KADAI_RCE_CALLBACK_URL = "%s/tc/loanAntiFraud/callback?functionCode=%s";

    @Value(value = "${web-http-url}")
    private String webHttpUrl;
    @Reference(version = "1.0.0")
    private TianchengDataDubboService tianchengDataDubboService;
    @Reference(version = "1.0.0")
    private UserForbidDubboService userForbidDubboService;
    @Reference(version = "1.0.0")
    private TradeConfigDubboService tradeConfigDubboService;
    @Reference(version = "1.0.0")
    private ProjectDubboService projectDubboService;
    @Reference(version = "1.0.0")
    private UserYXCreditCardDubboService userYXCreditCardDubboService;
    @Autowired
    private TianchengAgainstFakeV2Service tianchengAgainstFakeV2Service;
    @Autowired
    private ProjectMapperExt projectMapperExt;
    @Autowired
    private LoanAntiFraudLocalService loanAntiFraudLocalService;
    @Autowired
    private ProjectFlowExecuteService projectFlowExecuteService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;
    @Autowired
    private CreditAmountLocalService creditAmountLocalService;
    @Autowired
    private SystemAuditDecisionLocalService systemAuditDecisionLocalService;


    @Override
    public void libraFraudSocialSecurityFirst(String userId, Long projectId, Long flowExecuteId) {
        log.info("发起标准化社保贷反欺诈-首借用户userId = {},projectId = {}", userId, projectId);
        LibraFraudCreditCardFirst libraFraudSocialSecurityFirst = new LibraFraudCreditCardFirst();
        Project project = projectMapperExt.selectByPrimaryKey(projectId);
        libraFraudSocialSecurityFirst.setOrder_id(String.valueOf(snowflakeIdWorker.nextId()));
        libraFraudSocialSecurityFirst.setProject_id(String.valueOf(projectId));
        libraFraudSocialSecurityFirst.setNotify_url(createAntiFraudCallbackUrl(FunctionCodeEnum.LIBRA_FRAUD_SOCIAL_SECURITY_FIRST));
        libraFraudSocialSecurityFirst.setFrom_source(AntifraudFromSourceEnum.SPEED_UP_THE_SOCIAL_SECURITY_LOAN.getFromSource());
        libraFraudSocialSecurityFirst.setReserve(String.valueOf(flowExecuteId));
        if (project != null) {
            libraFraudSocialSecurityFirst.setGps_province(project.getLoanProvince());
            libraFraudSocialSecurityFirst.setGps_city(project.getLoanCity());
            libraFraudSocialSecurityFirst.setGps_district(project.getLoanArea());
        }
        libraFraudSocialSecurityFirst.setTransDate(new Date());
        libraFraudSocialSecurityFirst.setTransNo(String.valueOf(projectId));
        TianchengCreditBaseInfoResponseDTO tianchengCreditBaseInfoResponseDTO = tianchengDataDubboService.getUserTianchengCreditBaseInfo(userId);
        if (tianchengCreditBaseInfoResponseDTO != null) {
            BasicInfoDTO basicInfoDTO = tianchengCreditBaseInfoResponseDTO.getBaseInfo();
            WorkInfoDTO workInfoDTO = tianchengCreditBaseInfoResponseDTO.getWorkInfo();
            List<ContactPersonInfoDTO> contactPersonInfoDTOS = tianchengCreditBaseInfoResponseDTO.getContacts();
            if (basicInfoDTO != null) {
                libraFraudSocialSecurityFirst.setBasic_info(TianchengModelParseService.parseBaseInfo(basicInfoDTO));
            }
            if (workInfoDTO != null) {
                libraFraudSocialSecurityFirst.setWork_info(TianchengModelParseService.parseWorkInfo(workInfoDTO));
            }
            if (!contactPersonInfoDTOS.isEmpty()) {
                libraFraudSocialSecurityFirst.setContact_person(TianchengModelParseService.parseContactPersonInfo(contactPersonInfoDTOS));
            }
        }
        try {
            log.info("发起标准化社保贷反欺诈-首借用户请求参数{}", JSONObject.toJSONString(libraFraudSocialSecurityFirst));
            CompletableFuture<AgainstFakeV2Response> completableFuture = tianchengAgainstFakeV2Service.libraFraudSocialSecurityFirst(libraFraudSocialSecurityFirst);
            AgainstFakeV2Response againstFakeV2Response = completableFuture.get();
            log.info("发起标准化社保贷反欺诈-首借用户结果解析{}", JSONObject.toJSONString(againstFakeV2Response));

            processTcResult(againstFakeV2Response, flowExecuteId, projectId, libraFraudSocialSecurityFirst.getOrder_id(), FunctionCodeEnum.LIBRA_FRAUD_SOCIAL_SECURITY_FIRST, userId);
        } catch (Exception ex) {
            projectFlowExecuteService.updateProjectFlowExecuteRuntime(flowExecuteId, LoanNodeTypeEnum.LOAN_ANTI_FRAUD, ProjectFlowExecuteRuntimeNodeStatusEnum.EXCEPTION, ex.getMessage());
            log.error("发起标准化社保贷反欺诈-首借用户异常{}", ex);
        }
    }

    @Override
    public void libraFraudSocialSecurityNotFirst(String userId, Long projectId, Long flowExecuteId) {
        log.info("标准化社保贷反欺诈-复借用户userId = {},projectId = {}", userId, projectId);
        LibraFraudSocialSecurityNotFirst libraFraudSocialSecurityNotFirst = new LibraFraudSocialSecurityNotFirst();
        libraFraudSocialSecurityNotFirst.setOrder_id(String.valueOf(snowflakeIdWorker.nextId()));
        libraFraudSocialSecurityNotFirst.setProject_id(String.valueOf(projectId));
        libraFraudSocialSecurityNotFirst.setNotify_url(createAntiFraudCallbackUrl(FunctionCodeEnum.LIBRA_FRAUD_SOCIAL_SECURITY_NOT_FIRST));
        libraFraudSocialSecurityNotFirst.setFrom_source(AntifraudFromSourceEnum.SPEED_UP_THE_SOCIAL_SECURITY_LOAN.getFromSource());
        libraFraudSocialSecurityNotFirst.setReserve(String.valueOf(flowExecuteId));
        libraFraudSocialSecurityNotFirst.setTransDate(new Date());
        libraFraudSocialSecurityNotFirst.setTransNo(String.valueOf(projectId));
        TianchengCreditBaseInfoResponseDTO tianchengCreditBaseInfoResponseDTO = tianchengDataDubboService.getUserTianchengCreditBaseInfo(userId);
        if (tianchengCreditBaseInfoResponseDTO != null) {
            BasicInfoDTO basicInfoDTO = tianchengCreditBaseInfoResponseDTO.getBaseInfo();
            if (basicInfoDTO != null) {
                libraFraudSocialSecurityNotFirst.setBasic_info(TianchengModelParseService.parseBaseInfo(basicInfoDTO));
            }
        }
        try {
            log.info("标准化社保贷反欺诈-复借用户请求参数{}", JSONObject.toJSONString(libraFraudSocialSecurityNotFirst));
            CompletableFuture<AgainstFakeV2Response> completableFuture = tianchengAgainstFakeV2Service.libraFraudSocialSecurityNotFirst(libraFraudSocialSecurityNotFirst);
            AgainstFakeV2Response againstFakeV2Response = completableFuture.get();
            log.info("标准化社保贷反欺诈-复借用户结果解析{}", JSONObject.toJSONString(againstFakeV2Response));

            processTcResult(againstFakeV2Response, flowExecuteId, projectId, libraFraudSocialSecurityNotFirst.getOrder_id(), FunctionCodeEnum.LIBRA_FRAUD_SOCIAL_SECURITY_NOT_FIRST, userId);
        } catch (Exception ex) {
            projectFlowExecuteService.updateProjectFlowExecuteRuntime(flowExecuteId, LoanNodeTypeEnum.LOAN_ANTI_FRAUD, ProjectFlowExecuteRuntimeNodeStatusEnum.EXCEPTION, ex.getMessage());
            log.error("标准化社保贷反欺诈-复借用户异常{}", ex);
        }
    }

    @Override
    public void libraFraudCreditCardFirst(String userId, Long projectId, Long flowExecuteId) {
        log.info("标准化信用卡贷反欺诈-首借用户userId = {},projectId = {}", userId, projectId);
        LibraFraudCreditCardFirst libraFraudCreditCardFirst = new LibraFraudCreditCardFirst();
        Project project = projectMapperExt.selectByPrimaryKey(projectId);
        libraFraudCreditCardFirst.setOrder_id(String.valueOf(snowflakeIdWorker.nextId()));
        libraFraudCreditCardFirst.setProject_id(String.valueOf(projectId));
        libraFraudCreditCardFirst.setNotify_url(createAntiFraudCallbackUrl(FunctionCodeEnum.LIBRA_FRAUD_CREDIT_CARD_FIRST));
        libraFraudCreditCardFirst.setFrom_source(AntifraudFromSourceEnum.CREDIT_CARD_LOAN.getFromSource());
        libraFraudCreditCardFirst.setReserve(String.valueOf(flowExecuteId));
        libraFraudCreditCardFirst.setTransDate(new Date());
        libraFraudCreditCardFirst.setTransNo(String.valueOf(projectId));
        UserCreditCardAuthInfoDTO userCreditCardAuthInfoDTO = userYXCreditCardDubboService.queryUserCreditCardAuthInfo(userId);
        if (userCreditCardAuthInfoDTO == null) {
            log.info("标准化信用卡贷反欺诈-首借用户userId={},驭信信息不存在", userId);
            throw new BizException("TRD20011");
        }
        libraFraudCreditCardFirst.setYx_entry_id(userCreditCardAuthInfoDTO.getEntryId());
        libraFraudCreditCardFirst.setYx_login_name(userCreditCardAuthInfoDTO.getLoginName());
        if (project != null) {
            libraFraudCreditCardFirst.setGps_province(project.getLoanProvince());
            libraFraudCreditCardFirst.setGps_city(project.getLoanCity());
            libraFraudCreditCardFirst.setGps_district(project.getLoanArea());
        }
        TianchengCreditBaseInfoResponseDTO tianchengCreditBaseInfoResponseDTO = tianchengDataDubboService.getUserTianchengCreditBaseInfo(userId);
        if (tianchengCreditBaseInfoResponseDTO != null) {
            BasicInfoDTO basicInfoDTO = tianchengCreditBaseInfoResponseDTO.getBaseInfo();
            WorkInfoDTO workInfoDTO = tianchengCreditBaseInfoResponseDTO.getWorkInfo();
            List<ContactPersonInfoDTO> contactPersonInfoDTOS = tianchengCreditBaseInfoResponseDTO.getContacts();
            if (basicInfoDTO != null) {
                libraFraudCreditCardFirst.setBasic_info(TianchengModelParseService.parseBaseInfo(basicInfoDTO));
            }
            if (workInfoDTO != null) {
                libraFraudCreditCardFirst.setWork_info(TianchengModelParseService.parseWorkInfo(workInfoDTO));
            }
            if (!contactPersonInfoDTOS.isEmpty()) {
                libraFraudCreditCardFirst.setContact_person(TianchengModelParseService.parseContactPersonInfo(contactPersonInfoDTOS));
            }
        }
        try {
            log.info("标准化信用卡贷反欺诈-首借用户请求参数{}", JSONObject.toJSONString(libraFraudCreditCardFirst));
            CompletableFuture<AgainstFakeV2Response> completableFuture = tianchengAgainstFakeV2Service.libraFraudCreditCardFirst(libraFraudCreditCardFirst);
            AgainstFakeV2Response againstFakeV2Response = completableFuture.get();
            log.info("标准化信用卡贷反欺诈-首借用户结果解析{}", JSONObject.toJSONString(againstFakeV2Response));

            processTcResult(againstFakeV2Response, flowExecuteId, projectId, libraFraudCreditCardFirst.getOrder_id(), FunctionCodeEnum.LIBRA_FRAUD_CREDIT_CARD_FIRST, userId);
        } catch (Exception ex) {
            projectFlowExecuteService.updateProjectFlowExecuteRuntime(flowExecuteId, LoanNodeTypeEnum.LOAN_ANTI_FRAUD, ProjectFlowExecuteRuntimeNodeStatusEnum.EXCEPTION, ex.getMessage());
            log.error("标准化信用卡贷反欺诈-首借用户异常{}", ex);
        }
    }

    @Override
    public void libraFraudCreditCardNotFirst(String userId, Long projectId, Long flowExecuteId) {
        log.info("标准化信用卡贷反欺诈-复借用户userId = {},projectId = {}", userId, projectId);
        LibraFraudSocialSecurityNotFirst fraudSocialSecurityNotFirst = new LibraFraudSocialSecurityNotFirst();
        fraudSocialSecurityNotFirst.setOrder_id(String.valueOf(snowflakeIdWorker.nextId()));
        fraudSocialSecurityNotFirst.setProject_id(String.valueOf(projectId));
        fraudSocialSecurityNotFirst.setNotify_url(createAntiFraudCallbackUrl(FunctionCodeEnum.LIBRA_FRAUD_CREDIT_CARD_NOT_FIRST));
        fraudSocialSecurityNotFirst.setFrom_source(AntifraudFromSourceEnum.CREDIT_CARD_LOAN.getFromSource());
        fraudSocialSecurityNotFirst.setReserve(String.valueOf(flowExecuteId));
        fraudSocialSecurityNotFirst.setTransDate(new Date());
        fraudSocialSecurityNotFirst.setTransNo(String.valueOf(projectId));
        UserCreditCardAuthInfoDTO userCreditCardAuthInfoDTO = userYXCreditCardDubboService.queryUserCreditCardAuthInfo(userId);
        if (userCreditCardAuthInfoDTO == null) {
            log.info("标准化信用卡贷反欺诈-复借用户userId={},驭信信息不存在", userId);
            throw new BizException("TRD20011");
        }
        fraudSocialSecurityNotFirst.setYx_entry_id(userCreditCardAuthInfoDTO.getEntryId());
        fraudSocialSecurityNotFirst.setYx_login_name(userCreditCardAuthInfoDTO.getLoginName());
        TianchengCreditBaseInfoResponseDTO tianchengCreditBaseInfoResponseDTO = tianchengDataDubboService.getUserTianchengCreditBaseInfo(userId);
        if (tianchengCreditBaseInfoResponseDTO != null) {
            BasicInfoDTO basicInfoDTO = tianchengCreditBaseInfoResponseDTO.getBaseInfo();
            if (basicInfoDTO != null) {
                fraudSocialSecurityNotFirst.setBasic_info(TianchengModelParseService.parseBaseInfo(basicInfoDTO));
            }
        }
        try {
            log.info("标准化信用卡贷反欺诈-复借用户请求参数{}", JSONObject.toJSONString(fraudSocialSecurityNotFirst));
            CompletableFuture<AgainstFakeV2Response> completableFuture = tianchengAgainstFakeV2Service.libraFraudCreditCardNotFirst(fraudSocialSecurityNotFirst);
            AgainstFakeV2Response againstFakeV2Response = completableFuture.get();
            log.info("标准化信用卡贷反欺诈-复借用户结果解析{}", JSONObject.toJSONString(againstFakeV2Response));

            processTcResult(againstFakeV2Response, flowExecuteId, projectId, fraudSocialSecurityNotFirst.getOrder_id(), FunctionCodeEnum.LIBRA_FRAUD_CREDIT_CARD_NOT_FIRST, userId);
        } catch (Exception ex) {
            projectFlowExecuteService.updateProjectFlowExecuteRuntime(flowExecuteId, LoanNodeTypeEnum.LOAN_ANTI_FRAUD, ProjectFlowExecuteRuntimeNodeStatusEnum.EXCEPTION, ex.getMessage());
            log.error("标准化信用卡贷反欺诈-复借用户异常{}", ex);
        }
    }
    
    @Override
    public void libraFraudConsumeLoan(String userId, Long projectId, Long flowExecuteId) {
        log.info("标准化消费贷首借反欺诈，userId = {},projectId = {}", userId, projectId);
        
        Project project = projectMapperExt.selectByPrimaryKey(projectId);
        if (null == project) {
			log.error("标准化消费贷首借反欺诈异常：标的不存在，ProjectId：{}", projectId);
			projectFlowExecuteService.updateProjectFlowExecuteRuntime(flowExecuteId, LoanNodeTypeEnum.LOAN_ANTI_FRAUD, ProjectFlowExecuteRuntimeNodeStatusEnum.EXCEPTION, "标的不存在");
			return;
        }
        
		try {
	        // 构建请求参数
	        LibraFraudConsumeLoanRequest libraFraudConsumeLoanRequest = new LibraFraudConsumeLoanRequest();
	        
	        // RCE公有参数
	        libraFraudConsumeLoanRequest.setReserve(String.valueOf(flowExecuteId));
	        libraFraudConsumeLoanRequest.setTransDate(new Date());
	        libraFraudConsumeLoanRequest.setTransNo(String.valueOf(projectId));
	        
	        // 反欺诈相关参数
	        libraFraudConsumeLoanRequest.setOrder_id(String.valueOf(snowflakeIdWorker.nextId()));
	        libraFraudConsumeLoanRequest.setProject_id(String.valueOf(projectId));
	        libraFraudConsumeLoanRequest.setApply_amount(project.getContractAmount().doubleValue());
	        libraFraudConsumeLoanRequest.setFrom_source(AntifraudFromSourceEnum.CONSUME_LOAN.getFromSource());
	        libraFraudConsumeLoanRequest.setGps_province(project.getLoanProvince());
	        libraFraudConsumeLoanRequest.setGps_city(project.getLoanCity());
	        libraFraudConsumeLoanRequest.setGps_district(project.getLoanArea());
	        libraFraudConsumeLoanRequest.setNotify_url(createAntiFraudCallbackUrl(FunctionCodeEnum.LIBRA_FRAUD_CONSUME_LOAN));
	        libraFraudConsumeLoanRequest.setIs_multi_borrow(0);

	        // 用户信息（基础信息、工作信息、联系人信息）
	        TianchengCreditBaseInfoResponseDTO tianchengCreditBaseInfoResponseDTO = tianchengDataDubboService.getUserTianchengCreditBaseInfo(userId);
	        if (null != tianchengCreditBaseInfoResponseDTO) {
	            BasicInfoDTO basicInfoDTO = tianchengCreditBaseInfoResponseDTO.getBaseInfo();
	            WorkInfoDTO workInfoDTO = tianchengCreditBaseInfoResponseDTO.getWorkInfo();
	            List<ContactPersonInfoDTO> contactPersonInfoDTOList = tianchengCreditBaseInfoResponseDTO.getContacts();
	            if (null != basicInfoDTO) {
	                libraFraudConsumeLoanRequest.setBasic_info(TianchengModelParseService.parseBaseInfo(basicInfoDTO));
	            }
	            if (null != workInfoDTO) {
	            	libraFraudConsumeLoanRequest.setWork_info(TianchengModelParseService.parseWorkInfo(workInfoDTO));
	            }
	            if (!CollectionUtils.isEmpty(contactPersonInfoDTOList)) {
	            	libraFraudConsumeLoanRequest.setContact_person(TianchengModelParseService.parseContactPersonInfo(contactPersonInfoDTOList));
	            }
	        }			
			
			log.info("标准化消费贷首借反欺诈，请求参数：{}", JSONObject.toJSONString(libraFraudConsumeLoanRequest));
			CompletableFuture<AgainstFakeV2Response> completableFuture = tianchengAgainstFakeV2Service.libraFraudConsumeLoan(libraFraudConsumeLoanRequest);
			AgainstFakeV2Response againstFakeV2Response = completableFuture.get();
			log.info("标准化消费贷首借反欺诈，返回结果：{}", JSONObject.toJSONString(againstFakeV2Response));

			processTcResult(againstFakeV2Response, flowExecuteId, projectId, libraFraudConsumeLoanRequest.getOrder_id(), FunctionCodeEnum.LIBRA_FRAUD_CONSUME_LOAN, userId);
		} catch (Exception e) {
			log.error("标准化消费贷首借反欺诈请求异常，UserId = {},projectId = {}", userId, projectId, e);
			projectFlowExecuteService.updateProjectFlowExecuteRuntime(flowExecuteId, LoanNodeTypeEnum.LOAN_ANTI_FRAUD, ProjectFlowExecuteRuntimeNodeStatusEnum.EXCEPTION, e.getMessage());
		}
    }  
    
    @Override
    public void libraFraudConsumeLoanAgain(String userId, Long projectId, Long flowExecuteId) {
        log.info("标准化消费贷复借反欺诈，userId = {},projectId = {}", userId, projectId);
        
        Project project = projectMapperExt.selectByPrimaryKey(projectId);
        if (null == project) {
			log.error("标准化消费贷复借反欺诈异常：标的不存在，ProjectId：{}", projectId);
			projectFlowExecuteService.updateProjectFlowExecuteRuntime(flowExecuteId, LoanNodeTypeEnum.LOAN_ANTI_FRAUD, ProjectFlowExecuteRuntimeNodeStatusEnum.EXCEPTION, "标的不存在");
			return;
        }
        
		try {
	        // 构建请求参数
	        LibraFraudConsumeLoanAgainRequest libraFraudConsumeLoanAgainRequest = new LibraFraudConsumeLoanAgainRequest();
	        
	        // RCE公有参数
	        libraFraudConsumeLoanAgainRequest.setReserve(String.valueOf(flowExecuteId));
	        libraFraudConsumeLoanAgainRequest.setTransDate(new Date());
	        libraFraudConsumeLoanAgainRequest.setTransNo(String.valueOf(projectId));
	        
	        // 反欺诈相关参数
	        libraFraudConsumeLoanAgainRequest.setOrder_id(String.valueOf(snowflakeIdWorker.nextId()));
	        libraFraudConsumeLoanAgainRequest.setProject_id(String.valueOf(projectId));
	        libraFraudConsumeLoanAgainRequest.setApply_amount(project.getContractAmount().doubleValue());
	        libraFraudConsumeLoanAgainRequest.setFrom_source(AntifraudFromSourceEnum.CONSUME_LOAN.getFromSource());
	        libraFraudConsumeLoanAgainRequest.setNotify_url(createAntiFraudCallbackUrl(FunctionCodeEnum.LIBRA_FRAUD_CONSUME_LOAN_AGAIN));
	        libraFraudConsumeLoanAgainRequest.setIs_multi_borrow(1);
	        
	        // 授权信息
	        CreditScoreCardDTO creditScoreCardDTO = tianchengDataDubboService.queryCreditScoreCardParam(project.getBorrowUserId(), FunctionCodeEnum.LIBRA_CONSUME_LOAN.getHeadFunctionCode());
	        libraFraudConsumeLoanAgainRequest.setJd_auth(creditScoreCardDTO.getJd_auth());
	        libraFraudConsumeLoanAgainRequest.setJd_login_name(creditScoreCardDTO.getJd_login_name());
	        libraFraudConsumeLoanAgainRequest.setXx_auth(creditScoreCardDTO.getXx_auth());
	        libraFraudConsumeLoanAgainRequest.setYx_auth(creditScoreCardDTO.getYx_auth());
	        libraFraudConsumeLoanAgainRequest.setYx_entry_id(creditScoreCardDTO.getYx_entry_id());
	        libraFraudConsumeLoanAgainRequest.setYx_login_name(creditScoreCardDTO.getYx_login_name());

	        // 用户信息（基础信息、工作信息、联系人信息）
	        TianchengCreditBaseInfoResponseDTO tianchengCreditBaseInfoResponseDTO = tianchengDataDubboService.getUserTianchengCreditBaseInfo(userId);
	        if (null != tianchengCreditBaseInfoResponseDTO) {
	            BasicInfoDTO basicInfoDTO = tianchengCreditBaseInfoResponseDTO.getBaseInfo();
	            WorkInfoDTO workInfoDTO = tianchengCreditBaseInfoResponseDTO.getWorkInfo();
	            List<ContactPersonInfoDTO> contactPersonInfoDTOList = tianchengCreditBaseInfoResponseDTO.getContacts();
	            if (null != basicInfoDTO) {
	                libraFraudConsumeLoanAgainRequest.setBasic_info(TianchengModelParseService.parseBaseInfo(basicInfoDTO));
	            }
	            if (null != workInfoDTO) {
	            	libraFraudConsumeLoanAgainRequest.setWork_info(TianchengModelParseService.parseWorkInfo(workInfoDTO));
	            }
	            if (!CollectionUtils.isEmpty(contactPersonInfoDTOList)) {
	            	libraFraudConsumeLoanAgainRequest.setContact_person(TianchengModelParseService.parseContactPersonInfo(contactPersonInfoDTOList));
	            }
	        }
			
			log.info("标准化消费贷复借反欺诈，请求参数：{}", JSONObject.toJSONString(libraFraudConsumeLoanAgainRequest));
			CompletableFuture<AgainstFakeV2Response> completableFuture = tianchengAgainstFakeV2Service.libraFraudConsumeLoanAgain(libraFraudConsumeLoanAgainRequest);
			AgainstFakeV2Response againstFakeV2Response = completableFuture.get();
			log.info("标准化消费贷复借反欺诈，返回结果：{}", JSONObject.toJSONString(againstFakeV2Response));

			processTcResult(againstFakeV2Response, flowExecuteId, projectId, libraFraudConsumeLoanAgainRequest.getOrder_id(), FunctionCodeEnum.LIBRA_FRAUD_CONSUME_LOAN_AGAIN, userId);
		} catch (Exception e) {
			log.error("标准化消费贷复借反欺诈请求异常，UserId = {},projectId = {}", userId, projectId, e);
			projectFlowExecuteService.updateProjectFlowExecuteRuntime(flowExecuteId, LoanNodeTypeEnum.LOAN_ANTI_FRAUD, ProjectFlowExecuteRuntimeNodeStatusEnum.EXCEPTION, e.getMessage());
		}
    }    

    @Override
    public void libraFraudSmallLoanFirst(String userId, Long projectId, Long flowExecuteId) {
        log.info("标准化小易贷反欺诈-首借用户userId = {},projectId = {}", userId, projectId);
        LibraFraudCreditCardFirst libraFraudCreditCardFirst = new LibraFraudCreditCardFirst();
        Project project = projectMapperExt.selectByPrimaryKey(projectId);
        libraFraudCreditCardFirst.setOrder_id(String.valueOf(snowflakeIdWorker.nextId()));
        libraFraudCreditCardFirst.setProject_id(String.valueOf(projectId));
        libraFraudCreditCardFirst.setNotify_url(createAntiFraudCallbackUrl(FunctionCodeEnum.LIBRA_FRAUD_SMALL_LOAN_FIRST));
        libraFraudCreditCardFirst.setFrom_source(AntifraudFromSourceEnum.SPEED_BY_SMALL_LOAN.getFromSource());
        libraFraudCreditCardFirst.setReserve(String.valueOf(flowExecuteId));
        libraFraudCreditCardFirst.setTransDate(new Date());
        libraFraudCreditCardFirst.setTransNo(String.valueOf(projectId));
        if (project != null) {
            libraFraudCreditCardFirst.setGps_province(project.getLoanProvince());
            libraFraudCreditCardFirst.setGps_city(project.getLoanCity());
            libraFraudCreditCardFirst.setGps_district(project.getLoanArea());
        }
        TianchengCreditBaseInfoResponseDTO tianchengCreditBaseInfoResponseDTO = tianchengDataDubboService.getUserTianchengCreditBaseInfo(userId);
        if (tianchengCreditBaseInfoResponseDTO != null) {
            BasicInfoDTO basicInfoDTO = tianchengCreditBaseInfoResponseDTO.getBaseInfo();
            WorkInfoDTO workInfoDTO = tianchengCreditBaseInfoResponseDTO.getWorkInfo();
            List<ContactPersonInfoDTO> contactPersonInfoDTOS = tianchengCreditBaseInfoResponseDTO.getContacts();
            if (basicInfoDTO != null) {
                libraFraudCreditCardFirst.setBasic_info(TianchengModelParseService.parseBaseInfo(basicInfoDTO));
            }
            if (workInfoDTO != null) {
                libraFraudCreditCardFirst.setWork_info(TianchengModelParseService.parseWorkInfo(workInfoDTO));
            }
            if (!contactPersonInfoDTOS.isEmpty()) {
                libraFraudCreditCardFirst.setContact_person(TianchengModelParseService.parseContactPersonInfo(contactPersonInfoDTOS));
            }
        }
        try {
            log.info("标准化小易贷反欺诈-首借用户请求参数{}", JSONObject.toJSONString(libraFraudCreditCardFirst));
            CompletableFuture<AgainstFakeV2Response> completableFuture = tianchengAgainstFakeV2Service.libraFraudSmallLoanFirst(libraFraudCreditCardFirst);
            AgainstFakeV2Response againstFakeV2Response = completableFuture.get();
            log.info("标准化小易贷反欺诈-首借用户结果解析{}", JSONObject.toJSONString(againstFakeV2Response));

            processTcResult(againstFakeV2Response, flowExecuteId, projectId, libraFraudCreditCardFirst.getOrder_id(), FunctionCodeEnum.LIBRA_FRAUD_SMALL_LOAN_FIRST, userId);
        } catch (Exception ex) {
            projectFlowExecuteService.updateProjectFlowExecuteRuntime(flowExecuteId, LoanNodeTypeEnum.LOAN_ANTI_FRAUD, ProjectFlowExecuteRuntimeNodeStatusEnum.EXCEPTION, ex.getMessage());
            log.error("标准化小易贷反欺诈-首借用户异常{}", ex);
        }
    }

    @Override
    public void libraFraudSmallLoanNotFirst(String userId, Long projectId, Long flowExecuteId) {
        log.info("标准化小易贷反欺诈-复借用户userId = {},projectId = {}", userId, projectId);
        LibraFraudSocialSecurityNotFirst libraFraudSocialSecurityNotFirst = new LibraFraudSocialSecurityNotFirst();
        libraFraudSocialSecurityNotFirst.setOrder_id(String.valueOf(snowflakeIdWorker.nextId()));
        libraFraudSocialSecurityNotFirst.setProject_id(String.valueOf(projectId));
        libraFraudSocialSecurityNotFirst.setNotify_url(createAntiFraudCallbackUrl(FunctionCodeEnum.LIBRA_FRAUD_SMALL_LOAN_NOT_FIRST));
        libraFraudSocialSecurityNotFirst.setFrom_source(AntifraudFromSourceEnum.SPEED_BY_SMALL_LOAN.getFromSource());
        libraFraudSocialSecurityNotFirst.setReserve(String.valueOf(flowExecuteId));
        libraFraudSocialSecurityNotFirst.setTransDate(new Date());
        libraFraudSocialSecurityNotFirst.setTransNo(String.valueOf(projectId));
        TianchengCreditBaseInfoResponseDTO tianchengCreditBaseInfoResponseDTO = tianchengDataDubboService.getUserTianchengCreditBaseInfo(userId);
        if (tianchengCreditBaseInfoResponseDTO != null) {
            BasicInfoDTO basicInfoDTO = tianchengCreditBaseInfoResponseDTO.getBaseInfo();
            if (basicInfoDTO != null) {
                libraFraudSocialSecurityNotFirst.setBasic_info(TianchengModelParseService.parseBaseInfo(basicInfoDTO));
            }
        }
        try {
            log.info("标准化小易贷反欺诈-复借用户请求参数{}", JSONObject.toJSONString(libraFraudSocialSecurityNotFirst));
            CompletableFuture<AgainstFakeV2Response> completableFuture = tianchengAgainstFakeV2Service.libraFraudSmallLoanNotFirst(libraFraudSocialSecurityNotFirst);
            AgainstFakeV2Response againstFakeV2Response = completableFuture.get();
            log.info("标准化小易贷反欺诈-复借用户结果解析{}", JSONObject.toJSONString(againstFakeV2Response));

            processTcResult(againstFakeV2Response, flowExecuteId, projectId, libraFraudSocialSecurityNotFirst.getOrder_id(), FunctionCodeEnum.LIBRA_FRAUD_SMALL_LOAN_NOT_FIRST, userId);
        } catch (Exception ex) {
            projectFlowExecuteService.updateProjectFlowExecuteRuntime(flowExecuteId, LoanNodeTypeEnum.LOAN_ANTI_FRAUD, ProjectFlowExecuteRuntimeNodeStatusEnum.EXCEPTION, ex.getMessage());
            log.error("标准化小易贷反欺诈-复借用户异常{}", ex);

        }
    }

    /**
     * 创建天秤回调地址
     *
     * @param functionCodeEnum
     * @return
     */
    private String createAntiFraudCallbackUrl(FunctionCodeEnum functionCodeEnum) {
        String methodUrl = String.format(KADAI_RCE_CALLBACK_URL, webHttpUrl, functionCodeEnum.getHeadFunctionCode());
        return methodUrl;
    }

    @Transactional
    private void tianChengRequestRecord(String userId, Long projectId, Long flowExecuteId, FunctionCodeEnum functionCodeEnum) {
        TianChengRequestRecordDTO tianChengRequestRecordDTO = new TianChengRequestRecordDTO();
        tianChengRequestRecordDTO.setBorrowUserId(userId);
        tianChengRequestRecordDTO.setFlowExecuteId(flowExecuteId);
        tianChengRequestRecordDTO.setFunctionCode(functionCodeEnum.getHeadFunctionCode());
        tianChengRequestRecordDTO.setOrderId(String.valueOf(projectId));
        tianChengRequestRecordDTO.setProjectId(projectId);
        loanAntiFraudLocalService.tianChengRequestRecord(tianChengRequestRecordDTO);
    }

    @Override
    public void loanAntiFraudBack(AgainstFakeModelV2CallbackRequestDTO againstFakeModelV2CallbackRequestDTO) {
        log.info("5.1.5借款反欺诈天秤回调{}", JSONObject.toJSONString(againstFakeModelV2CallbackRequestDTO));
        ProjectFlowExecuteRuntimeDTO projectFlowExecuteRuntimeDTO = loanAntiFraudLocalService.queryById(againstFakeModelV2CallbackRequestDTO.getFlowExecuteId());

        //如果天秤回调时，发现当前节点不属于本业务逻辑，说明天秤属于重复调用，不予处理
        if (!LoanNodeTypeEnum.LOAN_ANTI_FRAUD.getId().equals(projectFlowExecuteRuntimeDTO.getNodeId())  &&
                !LoanNodeTypeEnum.LOAN_ANTI_FRAUD_BACK.getId().equals(projectFlowExecuteRuntimeDTO.getNodeId())){
        	log.error("流程节点异常,流程ID={}", againstFakeModelV2CallbackRequestDTO.getFlowExecuteId());
            return;
        }

        try {
            if (AgainstFakeErrorCodeEnum.SUCCESS.getErrorCode() == againstFakeModelV2CallbackRequestDTO.getStatus() && againstFakeModelV2CallbackRequestDTO.getDecision() != 1) {
                log.info("5.1.5借款反欺诈天秤回调正常{}",JSONObject.toJSONString(projectFlowExecuteRuntimeDTO));

                Project project = projectMapperExt.selectByPrimaryKey(projectFlowExecuteRuntimeDTO.getProjectId());
                if (!project.getStatus().equals(ProjectStatusEnum.CHECKING.getStatus())
                        || !project.getSubStatus().equals(ProjectSubStatusEnum.CHECKING_INIT.getSubStatus())) {
                    log.error("5.1.5借款反欺诈天秤回调,标的ID={},发生业务异常,原因是标的状态={},标的子状态={}", project.getProjectId(), project.getStatus(), project.getSubStatus());
                    return;
                }

                //更新标的状态
                updateProjectStatus(project, ProjectStatusEnum.CHECKING, ProjectSubStatusEnum.CHECKING_LOAN_FAKE_PASS);
                //流转到下一步
                projectFlowExecuteService.initNextStepProjectFlowExecute(againstFakeModelV2CallbackRequestDTO.getFlowExecuteId(), LoanNodeTypeEnum.LOAN_ANTI_FRAUD_BACK, LoanNodeTypeEnum.LOAN_LIMIT_SCORE, LoanFlowMqConstant.Queue.LOAN_LIMIT_SCORE_QUEUE);
            } else {
                log.info("5.1.5借款反欺诈天秤回调异常");
                //记录反欺诈失败原因
                List<AgainstFakeModelV2CallbackRequestDTO.BoolRule> boolRules = againstFakeModelV2CallbackRequestDTO.getResult().getDetail().getBool_rules();
                if (!boolRules.isEmpty()) {
                    for (AgainstFakeModelV2CallbackRequestDTO.BoolRule boolRule : boolRules) {
                        String hit = boolRule.getHit();
                        if ("命中".equals(hit) || "异常".equals(hit)) {
                            SystemAuditDecision systemAuditDecision = new SystemAuditDecision();
                            systemAuditDecision.setId(snowflakeIdWorker.nextId());
                            systemAuditDecision.setProjectId(projectFlowExecuteRuntimeDTO.getProjectId());
                            systemAuditDecision.setSystemAuditType(new Integer(1).byteValue());
                            systemAuditDecision.setAuditReason(boolRule.getRule_name());
                            systemAuditDecision.setRuleId(boolRule.getRule_id());
                            systemAuditDecision.setCreateTime(new Date());

                            systemAuditDecisionLocalService.saveSystemAuditDecision(systemAuditDecision);
                            break;
                        }
                    }
                }
                //更新标的状态   推送标的快照MQ
                updateProject(projectFlowExecuteRuntimeDTO);
                //加入行为限制
                AddUserLoanLimitRequestDTO addUserLoanLimitRequestDTO = new AddUserLoanLimitRequestDTO();
                addUserLoanLimitRequestDTO.setUserId(projectFlowExecuteRuntimeDTO.getBorrowUserId());
                //addUserLoanLimitRequestDTO.setProductTypeEnum(ProductTypeEnum.SPEED_LOAN); //限制所有类型所有注释掉
                addUserLoanLimitRequestDTO.setLimitType(LibraLoanLimitEnum.LOAN_AGAINST_FAKE.getLimitType().intValue());
                addUserLoanLimitRequestDTO.setLimitDays(Integer.valueOf(tradeConfigDubboService.selectTradeConfigByEmun(TradeConfigEnum.HITLOANANTIFRAUDLIMITDAYS)));
                userForbidDubboService.addUserLibraLoanLimitAllType(addUserLoanLimitRequestDTO);
                //流程结束
                projectFlowExecuteService.failEndProjectFlowExecute(againstFakeModelV2CallbackRequestDTO.getFlowExecuteId(), LoanNodeTypeEnum.LOAN_ANTI_FRAUD_BACK, againstFakeModelV2CallbackRequestDTO.getMessage());
            }
        } catch (Exception ex) {
            log.error("5.1.5借款反欺诈天秤回调异常projectId = {}",projectFlowExecuteRuntimeDTO.getProjectId(),ex);
            //如果流程记录都不存在则直接流标
            updateProject(projectFlowExecuteRuntimeDTO);
            //流程结束
            projectFlowExecuteService.failEndProjectFlowExecute(againstFakeModelV2CallbackRequestDTO.getFlowExecuteId(), LoanNodeTypeEnum.LOAN_ANTI_FRAUD_BACK, ex.getMessage());
        }

    }

    private void updateProjectStatus(Project project, ProjectStatusEnum projectStatusEnum, ProjectSubStatusEnum projectSubStatusEnum) {
        project.setStatus(projectStatusEnum.getStatus());
        project.setSubStatus(projectSubStatusEnum.getSubStatus());
        project.setUpdateTime(new Date());
        projectMapperExt.updateByUserIdProjectSelective(project);
    }

    /**
     * 流标
     * @param projectFlowExecuteRuntimeDTO
     */
    public void updateProject(ProjectFlowExecuteRuntimeDTO projectFlowExecuteRuntimeDTO){
        ProjectFlowRequestDTO projectFlowRequestDTO = new ProjectFlowRequestDTO();
        projectFlowRequestDTO.setProjectId(projectFlowExecuteRuntimeDTO.getProjectId());
        projectFlowRequestDTO.setSubStatus(ProjectSubStatusEnum.MISCARRY_LOAN_FAKE_FAILED);
        projectDubboService.flow(projectFlowRequestDTO);
    }
    @Override
    public void repairServiceAntiFraud(ProjectFlowExecuteRuntimeDTO projectFlowExecuteRuntimeDTO) {
        log.info("5.1.5借款反欺诈天秤补漏{}",JSONObject.toJSON(projectFlowExecuteRuntimeDTO));
        Long flowExecuteId = projectFlowExecuteRuntimeDTO.getFlowExecuteId();
        Byte projectType = projectFlowExecuteRuntimeDTO.getProjectType();
        Long projectId = projectFlowExecuteRuntimeDTO.getProjectId();
        try {
            Boolean firstLoan = loanAntiFraudLocalService.firstLoan(projectFlowExecuteRuntimeDTO.getBorrowUserId());
            FunctionCodeEnum functionCodeEnum = null;
            if (ProjectTypeEnum.SMALL_LOAN.getValue().equals(projectType) && firstLoan) {
                functionCodeEnum = FunctionCodeEnum.LIBRA_FRAUD_SMALL_LOAN_NOT_FIRST;
            } else if (ProjectTypeEnum.SMALL_LOAN.getValue().equals(projectType) && !firstLoan) {
                functionCodeEnum = FunctionCodeEnum.LIBRA_FRAUD_SMALL_LOAN_FIRST;
            } else if (ProjectTypeEnum.SOCIAL_SECURITY_LOAN.getValue().equals(projectType) && firstLoan) {
                functionCodeEnum = FunctionCodeEnum.LIBRA_FRAUD_SOCIAL_SECURITY_NOT_FIRST;
            } else if (ProjectTypeEnum.SOCIAL_SECURITY_LOAN.getValue().equals(projectType) && !firstLoan) {
                functionCodeEnum = FunctionCodeEnum.LIBRA_FRAUD_SOCIAL_SECURITY_FIRST;
            } else if (ProjectTypeEnum.CREDIT_CARD_LOAN.getValue().equals(projectType) && firstLoan) {
                functionCodeEnum = FunctionCodeEnum.LIBRA_FRAUD_CREDIT_CARD_NOT_FIRST;
            } else if (ProjectTypeEnum.CREDIT_CARD_LOAN.getValue().equals(projectType) && !firstLoan) {
                functionCodeEnum = FunctionCodeEnum.LIBRA_FRAUD_CREDIT_CARD_FIRST;
            } else if (ProjectTypeEnum.CONSUME_LOAN.getValue().equals(projectType)) {
            	functionCodeEnum = FunctionCodeEnum.LIBRA_FRAUD_CONSUME_LOAN;
            }
            TianChengRequestRecord tianChengRequestRecord = creditAmountLocalService.queryTcRequestRecord(flowExecuteId, functionCodeEnum.getHeadFunctionCode());
            if (tianChengRequestRecord != null) {
                KaDaiRepairServiceRequest kaDaiRepairServiceRequest = new KaDaiRepairServiceRequest();
                kaDaiRepairServiceRequest.setOrder_id(tianChengRequestRecord.getOrderId());
                kaDaiRepairServiceRequest.setTransDate(new Date());
                kaDaiRepairServiceRequest.setTransNo(String.valueOf(projectId));
                kaDaiRepairServiceRequest.setReserve(String.valueOf(projectId));
                kaDaiRepairServiceRequest.setTransDate(new Date());
                kaDaiRepairServiceRequest.setTransNo(String.valueOf(projectId));
                CompletableFuture<AgainstFakeV2Response> completableFuture = tianchengAgainstFakeV2Service.repairService(kaDaiRepairServiceRequest);
                AgainstFakeV2Response fakeV2Response = completableFuture.get();
                log.info("5.1.5借款反欺诈补漏服务fakeV2Response = {}", JSONObject.toJSONString(fakeV2Response));
                Project project = projectMapperExt.selectByPrimaryKey(projectId);
                if (fakeV2Response.getCode() != null && fakeV2Response.getCode() == 0
                        && JSONObject.parseObject(fakeV2Response.getBody()).getInteger("decision") != 1) {
                    //更新标的状态
                    updateProjectStatus(project, ProjectStatusEnum.CHECKING, ProjectSubStatusEnum.CHECKING_LOAN_FAKE_PASS);
                    //流转到下一步
                    projectFlowExecuteService.initNextStepProjectFlowExecute(flowExecuteId, LoanNodeTypeEnum.LOAN_ANTI_FRAUD_BACK, LoanNodeTypeEnum.LOAN_LIMIT_SCORE, LoanFlowMqConstant.Queue.LOAN_LIMIT_SCORE_QUEUE);
                } else {
                    //更新标的状态 推送标的快照MQ
                    updateProject(projectFlowExecuteRuntimeDTO);
                    //加入行为限制
                    AddUserLoanLimitRequestDTO addUserLoanLimitRequestDTO = new AddUserLoanLimitRequestDTO();
                    addUserLoanLimitRequestDTO.setUserId(project.getBorrowUserId());
                    //addUserLoanLimitRequestDTO.setProductTypeEnum(ProductTypeEnum.SPEED_LOAN); //限制所有类型所有注释掉
                    addUserLoanLimitRequestDTO.setLimitType(LibraLoanLimitEnum.LOAN_AGAINST_FAKE.getLimitType().intValue());
                    addUserLoanLimitRequestDTO.setLimitDays(Integer.valueOf(tradeConfigDubboService.selectTradeConfigByEmun(TradeConfigEnum.HITLOANANTIFRAUDLIMITDAYS)));
                    userForbidDubboService.addUserLibraLoanLimitAllType(addUserLoanLimitRequestDTO);
                    //流程结束
                    projectFlowExecuteService.failEndProjectFlowExecute(flowExecuteId, LoanNodeTypeEnum.LOAN_ANTI_FRAUD_BACK, fakeV2Response.getCode_desc());
                }
            } else {
            	//如果流程记录都不存在则直接流标
                updateProject(projectFlowExecuteRuntimeDTO);
            	
                // 没有对应请求记录，流程结束
                projectFlowExecuteService.failEndProjectFlowExecute(flowExecuteId, LoanNodeTypeEnum.LOAN_ANTI_FRAUD_BACK, "天秤请求记录不存在");
            }
        } catch(Exception ex) {
        	//如果流程记录都不存在则直接流标
            updateProject(projectFlowExecuteRuntimeDTO);
            
            //流程结束
            projectFlowExecuteService.failEndProjectFlowExecute(flowExecuteId, LoanNodeTypeEnum.LOAN_ANTI_FRAUD_BACK, ex.getMessage());
        }
    }

    @Override
    public void retryTime(ProjectFlowExecuteRuntimeDTO projectFlowExecuteRuntimeDTO) {
        log.info("5.1.5借款反欺诈重试{}", JSONObject.toJSONString(projectFlowExecuteRuntimeDTO));
        String userId = null;
        Long projectId = 0L;
        Long flowExecuteId = 0L;

        try {
            if (projectFlowExecuteRuntimeDTO == null) {
                log.info("5.1.5借款反欺诈重试对象为空");
                return;
            }
            if(projectFlowExecuteRuntimeDTO.getRetryTimes() > 3){
                log.info("5.1.5借款反欺诈重试次数已满{}",projectFlowExecuteRuntimeDTO.getRetryTimes());
                return;
            }
            userId = projectFlowExecuteRuntimeDTO.getBorrowUserId();
            projectId = projectFlowExecuteRuntimeDTO.getProjectId();
            flowExecuteId = projectFlowExecuteRuntimeDTO.getFlowExecuteId();
            ProjectTypeEnum projectTypeEnum = ProjectTypeEnum.getEnum(projectFlowExecuteRuntimeDTO.getProjectType());
            if (projectTypeEnum == null) {
                throw new BizException("TRD20008");
            }
            if(userId == null || projectId == 0 || flowExecuteId == 0){
                log.info("5.1.5借款反欺诈重试基础条件不满足userId = {},projectId = {},flowExecuteId = {}",userId,projectId,flowExecuteId);
                return;
            }
            Boolean isMultiBorrow = loanAntiFraudLocalService.firstLoan(userId);
            switch (projectTypeEnum) {
                case SMALL_LOAN:
                    if (isMultiBorrow) {
                        libraFraudSmallLoanNotFirst(userId, projectId, flowExecuteId);
                    } else {
                        libraFraudSmallLoanFirst(userId, projectId, flowExecuteId);
                    }
                    break;
                case SOCIAL_SECURITY_LOAN:
                    if (isMultiBorrow) {
                        libraFraudSocialSecurityNotFirst(userId, projectId, flowExecuteId);
                    } else {
                        libraFraudSocialSecurityFirst(userId, projectId, flowExecuteId);
                    }
                    break;
                case CREDIT_CARD_LOAN:
                    if (isMultiBorrow) {
                        libraFraudCreditCardNotFirst(userId, projectId, flowExecuteId);
                    } else {
                        libraFraudCreditCardFirst(userId, projectId, flowExecuteId);
                    }
                    break;
                case CONSUME_LOAN:
                	if(isMultiBorrow){
                		libraFraudConsumeLoanAgain(userId, projectId, flowExecuteId);
                	} else {
                		libraFraudConsumeLoan(userId, projectId, flowExecuteId);
                	}                	
                	
                    break;                    
                default:
                    break;
            }
        } catch (Exception ex) {
            log.error("借款反欺诈重试异常userId = {},projectId = {},flowExecuteId = {},异常堆栈={}", userId, projectId, flowExecuteId, ex);
        }
    }

    /**
     * 处理天秤反欺诈请求结果
     * @param againstFakeV2Response
     */
    private void processTcResult(AgainstFakeV2Response againstFakeV2Response, Long flowExecuteId, Long projectId, String orderId, FunctionCodeEnum functionCodeEnum, String userId) {
        StringBuffer errMsg = new StringBuffer("flowExecuteId=").append(flowExecuteId).append(" projectId=").append(projectId);
        errMsg.append("【发起标准化反欺诈】响应错误码:");
        errMsg.append(againstFakeV2Response.getCode());

        // 请求响应成功，更新节点到下一步
        if (AgainstFakeErrorCodeEnum.SUCCESS.getErrorCode() == againstFakeV2Response.getCode()){
            projectFlowExecuteService.initNextStepProjectTianchengRequest(flowExecuteId, LoanNodeTypeEnum.LOAN_ANTI_FRAUD, LoanNodeTypeEnum.LOAN_ANTI_FRAUD_BACK, null, orderId, functionCodeEnum, userId, projectId);

        //请求响应（参数错误、数据异常、其它错误）结束流程
        } else if (AgainstFakeErrorCodeEnum.PRAM_ERROR.getErrorCode() == againstFakeV2Response.getCode() ||
                AgainstFakeErrorCodeEnum.DATA_ABNORMAL.getErrorCode() == againstFakeV2Response.getCode() ||
                AgainstFakeErrorCodeEnum.OTHER_ERROR.getErrorCode() == againstFakeV2Response.getCode()){
            //流标
            creditAmountLocalService.flowProject(projectId);
            //结束流程
            projectFlowExecuteService.failEndProjectFlowExecute(flowExecuteId, LoanNodeTypeEnum.LOAN_ANTI_FRAUD, errMsg.toString());

        // 请求响应（获取数据超时、服务忙，稍后重试）更新为异常流程，后续重试
        } else {
            projectFlowExecuteService.updateProjectFlowExecuteRuntime(flowExecuteId, LoanNodeTypeEnum.LOAN_ANTI_FRAUD, ProjectFlowExecuteRuntimeNodeStatusEnum.EXCEPTION, errMsg.toString());
        }
    }

    /**
     * 推送标的快照MQ
     *
     * @param userId
     * @param projectId
     * @param projectType
     */
    private void loanSnapdata(String userId, Long projectId, Byte projectType) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("projectId", projectId);
        jsonObject.put("borrowerUserId", userId);
        jsonObject.put("productType", projectType);
        log.info("推标,标的ID={},发送标的快照MQ开始,请求参数={}", projectId, JSON.toJSONString(jsonObject));
        rabbitTemplate.convertAndSend(MqConstant.CREATE_PROJECT_SNAPSHOT_EXCHANGE, MqConstant.CREATE_PROJECT_SNAPSHOT_ROUTE, JSON.toJSONString(jsonObject));
    }
}
